from io import StringIO

def show(ast, buf=None, offset=0, attrnames=False, showlineno=True):
    if buf is None:
        buf = StringIO()  # 创建一个 StringIO 对象以捕获输出
    indent = 2
    lead = ' ' * offset

    buf.write(lead + ast.__class__.__name__ + ': ')

    if ast.attr_names:
        if attrnames:
            nvlist = [(n, getattr(ast, n)) for n in ast.attr_names]
            attrstr = ', '.join('%s=%s' % (n, v) for (n, v) in nvlist)
        else:
            vlist = [getattr(ast, n) for n in ast.attr_names]
            attrstr = ', '.join('%s' % v for v in vlist)
        buf.write(attrstr)

    if showlineno:
        if hasattr(ast, 'end_lineno'):
            buf.write(' (from %s to %s)' % (ast.lineno, ast.end_lineno))
        else:
            buf.write(' (at %s)' % ast.lineno)

    buf.write('\n')

    for c in ast.children():
        c.show(buf, offset + indent, attrnames, showlineno)

    return buf.getvalue()  # 返回捕获的内容
